package com.boge.util.websocket;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import com.boge.core.model.entity.User;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;  
import org.springframework.web.socket.WebSocketSession;  
import org.springframework.web.socket.handler.TextWebSocketHandler;  

@Service
public class WebsocketEndPoint extends TextWebSocketHandler {  
	
	private static final Map<Integer, WebSocketSession> users;
	//用户标识
    private static final String CLIENT_ID = "userId";
    
//    public static int onlineNum = 0;
    
    public static final Map<Integer, User> onlineUserMap;
    
	static {
		users = new HashMap<Integer, WebSocketSession>();
		onlineUserMap = new HashMap<Integer, User>();
	}
	
	/**
	 * 连接建立成功之后，记录用户的连接标识，便于后面发信息，这里我是记录将id记录在Map集合中。
	 */
	@Override
	public void afterConnectionEstablished(WebSocketSession session)
			throws Exception {
		System.out.println("成功建立连接");
		
		Integer userId = getClientId(session);
		System.out.println("userId:" + userId);
		if (userId != null) {
			users.put(userId, session);
			session.sendMessage(new TextMessage("成功建立websocket连接"));
		}
		
//		synchronized (this) {
//			onlineNum ++;
//		}
		
	}
	
	/**
	 * 对H5 Websocket的send方法进行处理
	 */
    @Override  
    protected void handleTextMessage(WebSocketSession session,  
            TextMessage message) throws Exception {  
        System.out.println("handleTextMessage:");
        TextMessage returnMessage = new TextMessage(message.getPayload()+" received at server");
        try {
        	Integer userId = getClientId(session);
        	synchronized (this) {
//        		new WebsocketEndPoint().sendMessageToAllUsers(new TextMessage(onlineNum + ""));
        		new WebsocketEndPoint().sendMessageToAllUsers(new TextMessage(onlineUserMap.size() + ""));
    		}
//        	session.sendMessage(returnMessage);
		} catch (Exception e) {
			e.printStackTrace();
		}
    }
    
    /**
     * 连接出错处理，主要是关闭出错会话的连接，和删除在Map集合中的记录
     */
    @Override
    public void handleTransportError(WebSocketSession session,
    		Throwable exception) throws Exception {
    	if (session.isOpen()) {
			session.close();
		}
    	System.out.println("连接出错");
    	users.remove(getClientId(session));
    }
    
    /**
     * 连接已关闭，移除在Map集合中的记录。
     */
    @Override
    public void afterConnectionClosed(WebSocketSession session,
    		CloseStatus status) throws Exception {
    	System.out.println("连接已关闭:" + status);
    	users.remove(getClientId(session));
//    	synchronized (this) {
//			onlineNum --;
//			new WebsocketEndPoint().sendMessageToAllUsers(new TextMessage(onlineNum + ""));
//		}
    }
    
    /**
     * 发送消息给指定用户
     * @param clientId
     * @param message
     * @return
     */
    public boolean sendMessageToUser(Integer clientId, TextMessage message) {
    	System.out.println("users:" + users);
    	if (users.get(clientId) != null) {
			WebSocketSession session = users.get(clientId);
			System.out.println("session222:" + session);
			if (session.isOpen()) {
				try {
					session.sendMessage(message);
				} catch (IOException e) {
					e.printStackTrace();
					return false;
				}
				return true;
			}
		}
    	return false;
    }
    
    /**
     * 广播信息
     * @param message
     * @return
     */
    public boolean sendMessageToAllUsers(TextMessage message) {
    	boolean flag = true;
    	Set<Integer> cliendIds = users.keySet();
    	WebSocketSession session = null;
    	for (Integer clientId : cliendIds) {
			try {
				System.out.println("clientId:" + clientId);
				session = users.get(clientId);
				if (session.isOpen()) {
					session.sendMessage(message);
				}
			} catch (Exception e) {
				e.printStackTrace();
				flag = false;
			}
		}
    	return flag;
    }
    
    /**
     * 获取用户标识
     * @param session
     * @return
     */
    private Integer getClientId(WebSocketSession session) {
    	try {
			Integer clientId = (Integer) session.getAttributes().get(CLIENT_ID);
			return clientId;
		} catch (Exception e) {
			return null;
		}
    }
    
}
